//
//  LinkExportClient.m
//  Hyphenate
//
//  Created by cptech on 2017/11/13.
//  Copyright © 2017年 cptech_yj. All rights reserved.
//

#import "LinkExportClient.h"
@interface LinkExportClient () <ExportHandler,ExportErrorHandler,LKChatManager>


@end


@implementation LinkExportClient {
    
    ExportClient *client;
}

static LinkExportClient *_instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    
    // 由于alloc方法内部会调用allocWithZone: 所以我们只需要保证在该方法只创建一个对象即可
    dispatch_once(&onceToken,^{
        
        // 只执行1次的代码(这里面默认是线程安全的)
        _instance = [super allocWithZone:zone];
        
    });
    
    return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}
+ (instancetype)sharedClient{

    return [[self alloc] init];
}
#pragma mark - Public method
- (BOOL)openConnect{
    
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        //只允许执行一次
        client = [[ExportClient alloc] init];
    });
    [client onOpen:self];
    [client onError:self];
    [self initConnection];
    
    
    return _isConnected;
}
- (void)initConnection{
    NSError *error = nil;
    _isConnected =[client connect:@"121.41.20.11" port:8080 error:&error];
    _chatManager = self;
    if(error){
        NSLog(@"Open Connect ERROR:%@",error);
    }

}

- (BOOL)closeConnect{
    NSError *error = nil;
    _isConnected = [client close:&error];
    return _isConnected;
}
- (void)initializeSessionSuccessful:(void(^)(NSDictionary *result))successful error:(void(^)(LKError *err))error{
    //设置心跳包时间
    _retryInterval = 3;
    //初始化会话
    NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:@"device",@"device",@"os",@"os",@"os_version",@"os_version",@"app",@"app",@"app_version",@"app_version",@{},@"tag",nil];
    NSData *data = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil];
    LKHandler *handler = [[LKHandler alloc] init];
    handler.succeed = ^(NSDictionary *result) {
        successful(result);
    };
    handler.failure = ^(LKError *err) {
        error(err);
    };
    NSError *err0 =nil;
    [client syncSend:@"/v1/session/start" param:data callback:handler error:&err0];
    if(err0){
        NSLog(@"%@",err0);
        error((LKError *)err0);
    }
}
- (void)initSession{
    [self initializeSessionSuccessful:^(NSDictionary *result) {
        NSLog(@"sid = %@",result[@"body"][@"value"]);
        if(result[@"body"][@"value"])
            //存sid在磁盘上
            [[NSUserDefaults standardUserDefaults] setObject:result[@"body"][@"value"] forKey:@"sid"];
        [client setRequestProperty:@"sid" value:result[@"body"][@"value"]];
        if(_isAuthLoggedIn){
            //如果自动登陆
            [self loginWithUsername:@"" password:@""];
        }
    } error:^(LKError *err) {
        [self initSession];
    }];
}
- (void)heartbeatSuccessful:(void(^)(NSDictionary *result))successful error:(void(^)(LKError *err))error{
    __block LKHeartbeatHandler *handler = [[LKHeartbeatHandler alloc] init];
    handler.succeed = ^(NSDictionary *result) {
        successful(result);
    };
    handler.failure = ^(LKError *err) {
        error(err);
    };
    dispatch_queue_t queue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        NSError *err0 = nil;
        [client ping:_retryInterval param:nil callback:handler error:&err0];
        if(err0){
            NSLog(@"%@",err0);
            error((LKError *)err0);
        }
    });
}
- (LKError *) loginWithUsername:(NSString *)     aUsername
                       password:(NSString *)     aPassword{
    
   __block LKError *error = nil;
    NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:aUsername,@"id",aPassword,@"password",nil];
    
    NSData *data = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&error];
    
    LKLoginHandler *handler = [[LKLoginHandler alloc] init];

    handler.succeed = ^(NSDictionary *result) {

    };
    handler.failure = ^(LKError *err) {
        error = err;
    };
    [client syncSend:@"/v1/session/bind/uid" param:data callback:handler error:&error];
    return error;
}
- (void) loginWithUsername:(NSString *)aUsername
                  password:(NSString *)aPassword
                completion:(void(^)(NSString *aUsername, LKError *aError))aCompletionBlock{
    __block LKError *error = nil;
    NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:aUsername,@"id",aPassword,@"password",nil];
    
    NSData *data = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&error];
    
    LKLoginHandler *handler = [[LKLoginHandler alloc] init];
    
    handler.succeed = ^(NSDictionary *result) {
        aCompletionBlock(aUsername,error);
    };
    handler.failure = ^(LKError *err) {
        aCompletionBlock(aUsername,err);
    };
    
    [client syncSend:@"/v1/session/bind/uid" param:data callback:handler error:&error];
    if(error){
        aCompletionBlock(aUsername,error);
    }
}
- (void)logoutCompletion:(void(^)(LKError *aError))aCompletionBlock{
    __block  LKError *error = nil;
    LKLoginHandler *handler = [[LKLoginHandler alloc] init];
    
    handler.succeed = ^(NSDictionary *result) {
        aCompletionBlock(error);
    };
    handler.failure = ^(LKError *err) {
        aCompletionBlock(err);
    };
    
    [client asyncSend:@"/v1/session/unbind/uid" param:nil callback:handler error:&error];
    if(error){
        aCompletionBlock(error);
    }
}

- (void)getDeviceInfo:(void(^)(NSArray  <LKChatSession *> *sessionList, LKError *aError))aCompletionBlock{

    LKAcquireHandler *handler = [[LKAcquireHandler alloc] init];
    
    handler.succeed = ^(NSArray<LKChatSession *> *list) {
        aCompletionBlock(list,nil);
    };
    handler.failure = ^(LKError *err) {
        aCompletionBlock(nil , err);
    };
    NSError *err0 = nil;
    [client asyncSend:@"/v1/session/list" param:nil callback:handler error:&err0];
    if(err0){
        aCompletionBlock(nil , (LKError *)err0);
    }
}
- (NSString *)currentUsername{
    
    return [[NSUserDefaults standardUserDefaults] objectForKey:@"currentUsername"];
}
#pragma mark - OnOpen的回调

- (void)handle:(NSData*)header body:(NSData*)body{
    
    NSLog(@"%s",__func__);

    [self initSession];
    
    [self heartbeatSuccessful:^(NSDictionary *result) {
        NSLog(@"心跳包：header:%@,body:%@",result[@"header"][@"value"],result[@"body"][@"value"]);
    } error:^(LKError *err) {

    }];
}

#pragma mark - ExportErrorHandler
- (void)handle:(NSString *)err{
    NSLog(@"%@",err);
}
#pragma mark - LKChatManager 聊天管理
- (void)addDelegate:(id<LKChatManagerDelegate>)delegate{
    
    LKDelegateHandler *handler = [[LKDelegateHandler alloc] init];
    handler.succeed = ^(LKMessage *aMessage) {
        if([delegate respondsToSelector:@selector(messagesDidReceive:)]){
            //获取到消息的回调
            [delegate messagesDidReceive:aMessage];
        }
    };
    [client addMessageListener:@"/v1/message/listener" callback:handler];
}
- (void)removeDelegate{
    
    [client removeMessageListener:@"/v1/message/listener"];

}
- (void)sendMessage:(LKMessage *)aMessage progress:(void (^)(int))aProgressBlock completion:(void (^)(LKMessage *, LKError *))aCompletionBlock{
    
    
    LKTextMessageBody *body = (LKTextMessageBody *)aMessage.body;
    NSString *bodyType ;
    NSString *chatType;
    switch (body.type) {
        case LKMessageBodyTypeText:
            bodyType = @"text";
            break;
            
        default:
            break;
    }
    switch (aMessage.chatType) {
        case LKChatTypeChat:
            chatType = @"user";
            break;
            
        default:
            break;
    }
    NSDictionary *message = [NSDictionary dictionaryWithObjectsAndKeys:bodyType,@"type",body.text,@"message", nil];
    NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:aMessage.conversationId,@"msg_id",aMessage.from,@"from",chatType,@"type",aMessage.to,@"to",message ,@"msg",aMessage.ext,@"ext",nil];
    NSData *data = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil];
    LKSendMsgHandler *handler = [[LKSendMsgHandler alloc] init];
    
    handler.succeed = ^(LKMessage *aMessage) {
        aCompletionBlock(aMessage, nil);
    };
    handler.failure = ^(LKError *err) {
        aCompletionBlock(nil,err);
    };
    
    LKError *err0 = nil;
    [client asyncSend:@"/v1/send/message" param:data callback:handler error:&err0];
    if(err0){
        aCompletionBlock(nil,err0);
    }
    
}

- (void)deleteConversation:(NSString *)aConversationId
          isDeleteMessages:(BOOL)aIsDeleteMessages
                completion:(void (^)(NSString *aConversationId, LKError *aError))aCompletionBlock{
    
    
}
/*!
 *  \~chinese
 *  导入一组消息到DB
 *
 *  @param aMessages        消息列表<EMMessage>
 *  @param aCompletionBlock 完成的回调
 *
 */
- (void)importMessages:(NSArray *)aMessages
            completion:(void (^)(LKError *aError))aCompletionBlock{
    
    
}
- (void)updateMessage:(LKMessage *)aMessage
           completion:(void (^)(LKMessage *aMessage, LKError *aError))aCompletionBlock{
    
}
- (LKConversation *)getConversation:(NSString *)aConversationId
                               type:(LKConversationType)aType
                   createIfNotExist:(BOOL)aIfCreate{
    LKConversation *conversation = [[LKConversation alloc] init];
    return conversation;
    
}
- (void)asyncSendReadAckForMessage:(LKMessage *)aMessage{
    
    
}
- (void)asyncResendMessage:(LKMessage *)aMessage
                  progress:(void (^)(int progress))aProgressCompletion
                completion:(void (^)(LKMessage *message, LKError *error))aCompletion{
    
    
}
@end 
